// pharmacode/Pharmacode.js
// Pharmacode（制药码）编码器
// 用于药品包装的二进制条码，支持 3–131070 范围内的整数

import Barcode from '../Barcode.js';

/**
 * Pharmacode 条码类
 *
 * 编码规则：
 * - 仅支持整数 3 ≤ n ≤ 131070
 * - 从右到左构建编码：
 *   - 偶数：添加 "11100"，z = (z - 2) / 2
 *   - 奇数：添加 "100"，z = (z - 1) / 2
 * - 最后移除末尾两个 "0"
 *
 * 编码示例：
 *   输入: 3
 *   步骤:
 *     3 是奇数 → "100", z = (3-1)/2 = 1
 *     1 是奇数 → "100" + "100" = "100100", z = (1-1)/2 = 0
 *     结束，移除最后两个 0 → "1001"
 *   输出: "1001"
 *
 * 条码结构：
 *   - '1' = 黑条 (bar)
 *   - '0' = 白空 (space)
 *   - 宽窄比：'111' = 宽条，'1' = 窄条
 */
export class Pharmacode extends Barcode {
  /**
   * 构造函数
   * @param {string|number} data - 要编码的数字（字符串或数字）
   * @param {Object} options - 条码配置项
   */
  constructor(data, options) {
    super(data, options);

    const num = parseInt(data, 10);
    if (isNaN(num)) {
      throw new Error('Pharmacode: 输入必须为有效数字');
    }

    this.number = num;
  }

  /**
   * 编码核心逻辑
   * @returns {{ data: string, text: string }}
   */
  encode() {
    let z = this.number;
    let result = '';

    while (!isNaN(z) && z !== 0) {
      if (z % 2 === 0) {
        // 偶数：添加宽条模式 "11100"
        result = '11100' + result;
        z = (z - 2) / 2;
      } else {
        // 奇数：添加窄条模式 "100"
        result = '100' + result;
        z = (z - 1) / 2;
      }
    }

    // 移除最后两个 "0"（标准要求）
    result = result.slice(0, -2);

    return {
      data: result,
      text: this.text
    };
  }

  /**
   * 验证输入是否在有效范围内
   * @returns {boolean}
   */
  valid() {
    return this.number >= 3 && this.number <= 131070;
  }

  /**
   * 获取原始数字
   * @returns {number}
   */
  getValue() {
    return this.number;
  }
}